/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: DcmDsl.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: DCMDSL
*
* Revision:
* --------------------------------------------------------------------------------
* v0.1: 
* --Yueting.Ben, 2024-03-11 
* --Initial release

**********************************************************************************/

/** HEADER FILES **/
#include "DcmDsl.h"


/** MACRO DEFINITION **/


/** TYPEDEF DEFINITION **/
typedef struct
{
    uint8 indicationFlag;
    uint8 responseReqFlag;
    PduInfoType pduInfo;
    Dcm_MsgType negResBuffer;
    Dcm_DataBufferIndexType sduDataIndex;
    Dcm_ProgressType progress;
    DcmDslProtocolRowType* protocalRowPtr;
}DcmDsl_InfoType;



/** LOCAL DATA DECLARATION **/
static Dcm_SesCtrlType DcmDslSessionCtrlState = DCM_DEFAULT_SESSION;
static Dcm_SecLevelType DcmDslSecurityLevel = DCM_SEC_LEV_LOCKED;

DcmDsl_InfoType DcmDslInfo;


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/
Std_ReturnType DcmDsl_SetSesCtrlType(
    Dcm_SesCtrlType* SesCtrlType
);

Std_ReturnType DcmDsl_SetSecurityLevel(
    Dcm_SecLevelType SecurityLevel
);

Std_ReturnType DcmDsl_GetSesCtrlType(
    Dcm_SesCtrlType* SesCtrlType
);

Std_ReturnType DcmDsl_GetSecurityLevel(
    Dcm_SecLevelType* SecLevel
);


BufReq_ReturnType Dcm_Init(void);

static Std_ReturnType Dcm_Transmit(
    void
);

/** GLOBAL FUNCTION DECLARATION **/
BufReq_ReturnType Dcm_StartOfReception(
    PduIdType id,
    const PduInfoType* info,
    PduLengthType TpSduLength,
    PduLengthType* bufferSizePtr
);

BufReq_ReturnType Dcm_CopyRxData(
    PduIdType id,
    const PduInfoType* info,
    PduLengthType* bufferSizePtr
);

void Dcm_TpRxIndication(
    PduIdType id,
    Std_ReturnType result
);

BufReq_ReturnType Dcm_CopyTxData(
    PduIdType id,
    const PduInfoType* info,
    const RetryInfoType* retry,
    PduLengthType* availableDataPtr
);

void Dcm_TpTxConfirmation(
PduIdType id,
Std_ReturnType result
);

void Dcm_TxConfirmation(
    PduIdType TxPduId,
    Std_ReturnType result
);


void Dcm_MainFunction(void);

Std_ReturnType DcmDsl_Init(
    void
);

void DcmDsl_MainFunction(
    void
);


/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/
Std_ReturnType DcmDsl_SetSesCtrlType(
    Dcm_SesCtrlType* SesCtrlType
)
{
    Std_ReturnType retVal = E_NOT_OK;
    
    DcmDslSessionCtrlState = *SesCtrlType;
    
    return(retVal);
}

Std_ReturnType DcmDsl_SetSecurityLevel(
    Dcm_SecLevelType SecurityLevel
)
{
    Std_ReturnType retVal = E_NOT_OK;
    
    DcmDslSecurityLevel = SecurityLevel;

    return(retVal);
}

Std_ReturnType DcmDsl_GetSesCtrlType(
    Dcm_SesCtrlType* SesCtrlType
)
{
    Std_ReturnType retVal = E_NOT_OK;
    
    *SesCtrlType = DcmDslSessionCtrlState;

    return(retVal);
}

Std_ReturnType DcmDsl_GetSecurityLevel(
    Dcm_SecLevelType* SecLevel
)
{
    Std_ReturnType retVal = E_NOT_OK;
    
    *SecLevel = DcmDslSecurityLevel;

    return(retVal);
}

Std_ReturnType DcmDsl_Init(void)
{
    DcmDslSessionCtrlState = DCM_DEFAULT_SESSION;
    DcmDslSecurityLevel = DCM_SEC_LEV_LOCKED;
}

BufReq_ReturnType Dcm_Init(void)
{
    Dcm_InfoType* dcmInfoPtr;

    DcmDsl_Init();
}


BufReq_ReturnType Dcm_StartOfReception(
    PduIdType id,
    const PduInfoType* info,
    PduLengthType TpSduLength,
    PduLengthType* bufferSizePtr
)
{
    BufReq_ReturnType retVal = BUFREQ_OK;
    DcmDslProtocolRowType* protocolRowPtr;
    PduIdType rxPduIdIndex;

    if(DCM_PROGRESS_INITIAL == DcmDslInfo.progress)
    {
        for(rxPduIdIndex = 0u; rxPduIdIndex < DcmConf_DcmRxPduCfg_Pdu_Max; rxPduIdIndex++)
        {
            protocolRowPtr = (DcmDslProtocolRowType*)&DcmDslProtocolCfg.protocolRow[rxPduIdIndex];
            if(id == protocolRowPtr->connection.mainConnection.protocolRx.rxPduId)
            {
                if(TpSduLength <= protocolRowPtr->maximumResponseSize)
                {
                    DcmDslInfo.progress = DCM_PROGRESS_DATA_RECEPTION;
                    DcmDslInfo.pduInfo.SduDataPtr = protocolRowPtr->rxBufferPtr;
                    DcmDslInfo.pduInfo.SduLength = TpSduLength;
                    DcmDslInfo.sduDataIndex = 0u;
                    DcmDslInfo.protocalRowPtr = (DcmDslProtocolRowType*)&DcmDslProtocolCfg.protocolRow[rxPduIdIndex];
                    break;
                }
                else
                {
                    retVal = BUFREQ_E_OVFL;
                }
            }
        }
    }
    else
    {
        retVal = BUFREQ_E_BUSY;
    }

    return(retVal);
}


BufReq_ReturnType Dcm_CopyRxData(
    PduIdType id,
    const PduInfoType* info,
    PduLengthType* bufferSizePtr
)
{
    BufReq_ReturnType retVal = BUFREQ_OK;

    if(DCM_PROGRESS_DATA_RECEPTION == DcmDslInfo.progress)
    {
        memcpy((uint8 *)(&DcmDslInfo.pduInfo.SduDataPtr[DcmDslInfo.sduDataIndex]), (uint8 *)(info->SduDataPtr), info->SduLength);
        DcmDslInfo.sduDataIndex += info->SduLength;
    }

    return(retVal);
}

void Dcm_TpRxIndication(
    PduIdType id,
    Std_ReturnType result
)
{
    DcmDslInfo.indicationFlag = SET;
    DcmDslInfo.progress = DCM_PROGRESS_IMPLEMENTATION;
}

BufReq_ReturnType Dcm_CopyTxData(
    PduIdType id,
    const PduInfoType* info,
    const RetryInfoType* retry,
    PduLengthType* availableDataPtr
)
{
    Dcm_InfoType* dcmInfoPtr;

    //if(DCM_PROGRESS_DATA_TRANSMISSION == DcmDslInfo.progress)
    {
        memcpy((uint8 *)(info->SduDataPtr), (uint8 *)(&DcmDslInfo.pduInfo.SduDataPtr[DcmDslInfo.sduDataIndex]), info->SduLength);
        DcmDslInfo.sduDataIndex += info->SduLength;
    }
    
    *availableDataPtr = DcmDslInfo.pduInfo.SduLength;
}

void Dcm_TpTxConfirmation(
PduIdType id,
Std_ReturnType result
)
{
    
}


void Dcm_TxConfirmation(
    PduIdType TxPduId,
    Std_ReturnType result
)
{
    DcmDslInfo.progress = DCM_PROGRESS_INITIAL;
}

static Std_ReturnType Dcm_Transmit(
    void
)
{
    DcmDslInfo.sduDataIndex = 0u;
    DcmDslInfo.progress = DCM_PROGRESS_DATA_TRANSMISSION;
    PduR_DcmTransmit(DcmDslInfo.protocalRowPtr->connection.mainConnection.protocolTx.txConfirmationPduId, (PduInfoType*)&DcmDslInfo.pduInfo);
}


void Dcm_MainFunction(void)
{

}


void DcmDsl_MainFunction(
    void
)
{
    Std_ReturnType retVal;
    Dcm_ExtendedOpStatusType OpStatus;
    static Dcm_NegativeResponseCodeType ErrorCode;
    
    if(SET == DcmDslInfo.indicationFlag)
    {
        retVal = DcmDsd_MainProcessor(OpStatus, (PduInfoType*)&DcmDslInfo.pduInfo, (Dcm_SvcCfgType*)(DcmDslInfo.protocalRowPtr->serviceTable), &ErrorCode);
        if(E_OK == retVal)
        {
            Dcm_Transmit();
            DcmDslInfo.indicationFlag = RESET;
            DcmDslInfo.progress = DCM_PROGRESS_INITIAL;
        }
        else if(E_NOT_OK == retVal)
        {
            DcmDslInfo.negResBuffer = Dcm_DslDiagResp;
            DcmDslInfo.negResBuffer[0] = 0x7F;
            DcmDslInfo.negResBuffer[1] = DcmDslInfo.pduInfo.SduDataPtr[0];
            DcmDslInfo.negResBuffer[2] = ErrorCode;
            
            DcmDslInfo.pduInfo.SduDataPtr = DcmDslInfo.negResBuffer;
            DcmDslInfo.pduInfo.SduLength = 3;
            Dcm_Transmit();
            DcmDslInfo.indicationFlag = RESET;
            DcmDslInfo.progress = DCM_PROGRESS_INITIAL;
        }
        else
        {
            /* Do nothing */
        }
    }
}
